package com.bjmashibing.system.huawei.vivo;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bjmashibing.system.huawei.Controller.HelloController;
import com.bjmashibing.system.huawei.jdbc.SpringJdbcTemplate;
import com.bjmashibing.system.huawei.static_var;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.gson.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Firebase Cloud Messaging (FCM) can be used to send messages to clients on iOS, Android and Web.
 *
 * This sample uses FCM to send two types of messages to clients that are subscribed to the `news`
 * topic. One type of message is a simple notification message (display message). The other is
 * a notification message (display notification) with platform specific customizations, for example,
 * a badge is added to messages that are sent to iOS devices.
 */
public class Messaging {
  private final static Logger logger = LoggerFactory.getLogger(Messaging.class);
  private static final String PROJECT_ID = "saferhome-4f7b4";
  private static final String BASE_URL = "https://fcm.googleapis.com";
  private static final String FCM_SEND_ENDPOINT = "/v1/projects/" + PROJECT_ID + "/messages:send";

  private static final String MESSAGING_SCOPE = "https://www.googleapis.com/auth/firebase.messaging";
  private static final String[] SCOPES = { MESSAGING_SCOPE };

  private static final String TITLE = "FCM Notification";
  private static final String BODY = "Notification from FCM";
  public static final String MESSAGE_KEY = "message";



  /**
   * Retrieve a valid access token that can be use to authorize requests to the FCM REST
   * API.
   *
   * @return Access token.   * @throws IOException
   */
  // [START retrieve_access_token]
  private static String getAccessToken() throws IOException {
    InputStream stream = Messaging.class.getClassLoader().getResourceAsStream("service_accounts/editor.json");
    GoogleCredential googleCredential = GoogleCredential
        .fromStream(stream)
        .createScoped(Arrays.asList(SCOPES));
    googleCredential.refreshToken();
//    logger.info("googleCredential=" + googleCredential);
    return googleCredential.getAccessToken();

  }
  // [END retrieve_access_token]

  /**
   * Create HttpURLConnection that can be used for both retrieving and publishing.
   *
   * @return Base HttpURLConnection.
   * @throws IOException
   */
  private static HttpURLConnection getConnection() throws IOException {
    // [START use_access_token]
    URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
//    logger.info("getAccessToken()=" + getAccessToken());
    httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessToken());
    httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
    return httpURLConnection;
    // [END use_access_token]
  }

  /**
   * Send request to FCM message using HTTP.
   *
   * @param fcmMessage Body of the HTTP request.
   * @throws IOException
   */
  private static void sendMessage(JsonObject fcmMessage) throws IOException {
    HttpURLConnection connection = getConnection();
    connection.setDoOutput(true);
    DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
    outputStream.writeBytes(fcmMessage.toString());
    outputStream.flush();
    outputStream.close();

    String str_token_fcm = fcmMessage.getAsJsonObject("message").get("token").getAsString();
//    logger.info("str_token_fcm = " + str_token_fcm);
    int responseCode = connection.getResponseCode();
    if (responseCode == 200) {
      String response = inputstreamToString(connection.getInputStream());
      logger.info("Message sent to Firebase for delivery, responseCode=:" + responseCode);
      logger.info("response = " + response);
      HelloController.handle_receipt_oppo_xiaomi(str_token_fcm,2);
    } else {
      logger.info("Unable to send message to Firebase:");
      String response = inputstreamToString(connection.getErrorStream());
      logger.info("response = " + response);
      JSONObject jsonObject = JSONObject.parseObject(response);
        logger.info("jsonObject=" + jsonObject);
      JSONObject error = jsonObject.getJSONObject("error");
      JSONArray details = error.getJSONArray("details");
      for (int i = 0; i < details.size(); i++) {
        JSONObject obj = (JSONObject) details.get(i);
        Map<String, Object> map_fcm = new HashMap<String, Object>();
        map_fcm = JSONObject.parseObject(obj.toJSONString(), Map.class);
        logger.info("@type=" + map_fcm.get("@type"));
        logger.info("errorCode=" + map_fcm.get("errorCode"));

        if (map_fcm.get("errorCode").toString().equals("UNREGISTERED")) {
          logger.info("UNREGISTERED......");
          SpringJdbcTemplate springJdbcTemplate = new SpringJdbcTemplate();
          springJdbcTemplate.token_queryForMap_huawei_receipt(str_token_fcm);
        }

      }
    }
  }

  /**
   * Send a message that uses the common FCM fields to send a notification message to all
   * platforms. Also platform specific overrides are used to customize how the message is
   * received on Android and iOS.
   *
   * @throws IOException
   */
  private static void sendOverrideMessage_language(String regid,String str_title,String str_big_body,String str_machine_account,String str_event_info,String str_language) throws IOException {
    JsonObject overrideMessage = buildOverrideMessage_language(regid,str_title,str_big_body,str_machine_account,str_event_info,str_language);
//    logger.info("FCM request body for override message:" + "," + str_machine_account);
    prettyPrint(overrideMessage);
    sendMessage(overrideMessage);
  }

  /**
   * Build the body of an FCM request. This body defines the common notification object
   * as well as platform specific customizations using the android and apns objects.
   *
   * @return JSON representation of the FCM request body.
   */
  private static JsonObject buildOverrideMessage_language(String regid,String str_title,String str_big_body,String str_machine_account,String str_event_info,String str_language) {
//    JsonObject jNotificationMessage = buildNotificationMessage_topic();


    JsonObject jNotificationMessage = buildNotificationMessage_token_language(regid,str_title,str_big_body,str_machine_account,str_event_info,str_language);

    /*JsonObject messagePayload = jNotificationMessage.get(MESSAGE_KEY).getAsJsonObject();
    messagePayload.add("android", buildAndroidOverridePayload());*/

    /*JsonObject apnsPayload = new JsonObject();
    apnsPayload.add("headers", buildApnsHeadersOverridePayload());
    apnsPayload.add("payload", buildApsOverridePayload());

    messagePayload.add("apns", apnsPayload);*/

//    jNotificationMessage.add(MESSAGE_KEY, messagePayload);


    return jNotificationMessage;
  }

  /**
   * Build the android payload that will customize how a message is received on Android.
   *
   * @return android payload of an FCM request.
   */
  private static JsonObject buildAndroidOverridePayload() {
    JsonObject androidNotification = new JsonObject();
//    androidNotification.addProperty("click_action", "android.intent.action.MAIN");
    androidNotification.addProperty("click_action", "MainActivity");

    JsonObject androidNotificationPayload = new JsonObject();
    androidNotificationPayload.add("notification", androidNotification);

    return androidNotificationPayload;
  }

  /**
   * Build the apns payload that will customize how a message is received on iOS.
   *
   * @return apns payload of an FCM request.
   */
  private static JsonObject buildApnsHeadersOverridePayload() {
    JsonObject apnsHeaders = new JsonObject();
    apnsHeaders.addProperty("apns-priority", "10");

    return apnsHeaders;
  }

  /**
   * Build aps payload that will add a badge field to the message being sent to
   * iOS devices.
   *
   * @return JSON object with aps payload defined.
   */
  private static JsonObject buildApsOverridePayload() {
    JsonObject badgePayload = new JsonObject();
    badgePayload.addProperty("badge", 1);

    JsonObject apsPayload = new JsonObject();
    apsPayload.add("aps", badgePayload);

    return apsPayload;
  }

  /**
   * Send notification message to FCM for delivery to registered devices.
   *
   * @throws IOException
   */
  public static void sendCommonMessage() throws IOException {
    JsonObject notificationMessage = buildNotificationMessage_topic();
    logger.info("FCM request body for message using common notification object:");
    prettyPrint(notificationMessage);
    sendMessage(notificationMessage);
  }

  /**
   * Construct the body of a notification message request.
   *
   * @return JSON of notification message.
   */
  private static JsonObject buildNotificationMessage_topic() {
    JsonObject jNotification = new JsonObject();
    jNotification.addProperty("title", TITLE);
    jNotification.addProperty("body", BODY);

    JsonObject jMessage = new JsonObject();
    jMessage.add("notification", jNotification);
    jMessage.addProperty("topic", "weather");

    JsonObject jData = new JsonObject();
    jData.addProperty("name", "wangyuhong");
    jData.addProperty("age", "22");
    jMessage.add("data", jData);


    JsonObject jFcm = new JsonObject();
    jFcm.add(MESSAGE_KEY, jMessage);

    return jFcm;
  }

  private static int get_event_type(String str_cid) {
    String str_cid_event = str_cid.substring(1,5);
//        logger.info("get_event_type,str_cid_event=" + str_cid_event);

        if (str_cid_event.contains("1110")) {
          return 1;
        }else if (str_cid_event.contains("1131")) {//Perimeter
          return 4;
        }else if (str_cid_event.contains("1130")) {//Burglar
          return 4;
        }else if (str_cid_event.contains("1120")) {//Emergency
          return 5;
        }else if (str_cid_event.contains("1121")) {//Help
          return 5;
        }else if (str_cid_event.contains("1151")) {//Gas
          return 2;
        }else if (str_cid_event.contains("1113")) {//Water
          return 3;
        }else if (str_cid_event.contains("1380")) {//Abnormal Detector
          return 99;
        }else if (str_cid_event.contains("1384")) {//Low Battery
          return 99;
        }else if (str_cid_event.contains("1383")) {//Tamper
          return 99;
        }else if (str_cid_event.contains("1100")) {//Medical
          return 99;
        }else if (str_cid_event.contains("1400")) {//Disarm
          return 99;
        }else if (str_cid_event.contains("3400")) {//All Arm
          return 99;
        }else if (str_cid_event.contains("1456")) {//Part Arm
          return 99;
        }else if (str_cid_event.contains("1301")) {//Electric City Low Battery
          return 99;
        }else if (str_cid_event.contains("1302")) {//Spare battery Low Battery
          return 99;
        }else if (str_cid_event.contains("3301")) {//Electric City Low Battery Restore
          return 99;
        }else if (str_cid_event.contains("3302")) {//Spare battery Low Battery Restore
          return 99;
        }



    return -1;
  }

  private static String get_event_denfence_number(String str_two_defence_number) {
    if (str_two_defence_number.equals("")) {
      return "";
    }
    if (str_two_defence_number.contains("01")
            || str_two_defence_number.contains("02")
            || str_two_defence_number.contains("03")
            || str_two_defence_number.contains("04")
            || str_two_defence_number.contains("05")
            || str_two_defence_number.contains("06")
            || str_two_defence_number.contains("07")
            || str_two_defence_number.contains("08")
            || str_two_defence_number.contains("09")


    ) {
      return str_two_defence_number.substring(1, 2);
    }else{
      return str_two_defence_number;
    }

  }

  private static JsonObject buildNotificationMessage_token_language(String regid,String str_title,String str_big_body,
                                                                    String str_machine_account,String str_event_info,String str_language) {

//    logger.info("buildNotificationMessage_token,str_title=" + str_title);
//    logger.info("buildNotificationMessage_token,str_big_body=" + str_big_body);
//    logger.info("buildNotificationMessage_token,str_event_info=" + str_event_info);

    int event_type = -1;
    event_type = get_event_type(str_event_info);
    logger.info("buildNotificationMessage_token,event_type=" + event_type);

    JsonObject jNotification = new JsonObject();
    String str_title2 = "";
    if (str_title.contains(static_var.str_120_var_en)) {
      str_title2 = "Help";
      jNotification.addProperty("title", str_title2);
    }else{
      jNotification.addProperty("title", str_title);
    }




    String str_controller_source = static_var.get_controller_source(str_event_info.substring(9, 12));

    String str_event_defence_number = get_event_denfence_number(str_event_info.substring(10,12));





    String str_body_temp = "";
    if (str_language.contains("English")) {
      if (str_title.contains(static_var.str_3400_var_en)) {//Arm
        str_body_temp = "By User:" + str_controller_source;
      } else if (str_title.contains(static_var.str_1400_var_en)){//Disarm
        str_body_temp = "By User:" + str_controller_source;
      }else if (str_title.contains(static_var.str_120_var_en)){//Emergency
        str_body_temp = "By User:" + str_controller_source;

      }else if (str_title.contains(static_var.str_121_var_en)){//Help
        str_body_temp = "Zone No.:" + str_event_defence_number;
      }else if (str_title.contains(static_var.str_130_var_en)){//Burgular
        str_body_temp = "Zone No.:" + str_event_defence_number;
      }else if (str_title.contains(static_var.str_151_var_en)){//Gas
        str_body_temp = "Zone No.:" + str_event_defence_number;
      }else if (str_title.contains(static_var.str_113_var_en)){//Water
        str_body_temp = "Zone No.:" + str_event_defence_number;
      }else if (str_title.contains(static_var.str_110_var_en)){//Fire

        str_body_temp = "Zone No.:" + str_event_defence_number;
      }
    }else {

    }


//    jNotification.addProperty("body", str_big_body);
    jNotification.addProperty("body", str_body_temp);


    JsonObject jMessage = new JsonObject();
    jMessage.add("notification", jNotification);
    jMessage.addProperty("token", regid);


    JsonObject jNotification3 = new JsonObject();
    if(event_type == -1){
      jNotification3.addProperty("channel_id", "RingRing_default");
    }else if(event_type == 1){
      jNotification3.addProperty("channel_id", "RingRing_fire");
    }else if(event_type == 2){
      jNotification3.addProperty("channel_id", "RingRing_gas");
    }else if(event_type == 3){
      jNotification3.addProperty("channel_id", "RingRing_water");
    }else if(event_type == 5){
      jNotification3.addProperty("channel_id", "RingRing_help_or_emergency");
    }else if(event_type == 4){
      jNotification3.addProperty("channel_id", "RingRing_robber");
    }else if(event_type == 99){
      jNotification3.addProperty("channel_id", "RingRing_default");
    }else{
      jNotification3.addProperty("channel_id", "RingRing_default");
    }
//    jNotification3.addProperty("default_vibrate_timings", true);
//    jNotification3.addProperty("default_light_settings", true);
  /*  JsonObject jNotification_priority = new JsonObject();
//    jNotification_priority.addProperty("priority", "normal");
    jNotification_priority.addProperty("priority", "high");*/
//    jNotification3.addProperty("channel_id", "RingRing");
//    jNotification3.addProperty("sound", "paizhao");
//    jNotification3.addProperty("sound", "sos2");


    JsonObject jNotification2 = new JsonObject();
    jNotification2.add("notification", jNotification3);


    jNotification2.addProperty("priority", "high");



    jMessage.add("android", jNotification2);



    JsonObject jData = new JsonObject();
    jData.addProperty("name", "wangyuhong");
    jData.addProperty("age", "22");
    jData.addProperty("machine_account", str_machine_account);
    jData.addProperty("event_info", str_event_info);
    jMessage.add("data", jData);


    JsonObject jFcm = new JsonObject();
    jFcm.add(MESSAGE_KEY, jMessage);


    return jFcm;
  }

  /**
   * Read contents of InputStream into String.
   *
   * @param inputStream InputStream to read.
   * @return String containing contents of InputStream.
   * @throws IOException
   */
  private static String inputstreamToString(InputStream inputStream) throws IOException {
    StringBuilder stringBuilder = new StringBuilder();
    Scanner scanner = new Scanner(inputStream);
    while (scanner.hasNext()) {
      stringBuilder.append(scanner.nextLine());
    }
    return stringBuilder.toString();
  }

  /**
   * Pretty print a JsonObject.
   *
   * @param jsonObject JsonObject to pretty print.
   */
  private static void prettyPrint(JsonObject jsonObject) {
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    logger.info("result_sumsamg = " + gson.toJson(jsonObject) + "\n");
  }

  /*public static void main(String[] args) throws IOException {


    System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
    //HTTP代理
    System.setProperty("http.proxyHost","127.0.0.1");
    System.setProperty("http.proxyPort",Integer.toString(1081));
    //HTTPS代理
    System.setProperty("https.proxyHost","127.0.0.1");
    System.setProperty("https.proxyPort",Integer.toString(1081));
    try {
      Messaging.send_message_fcm_to_regid("eh-PBbr1R8eH5nEKkVq-BQ:APA91bGjZbTdqJmSZa3BZYMPBGJ6U2RKgfoCecUhjahm6XKptnBfa6i49cnVycXZ0f6RkjGuICVGRt-gUa1RmWn9QIlNuEMZMt3DzIRvqFB2Y-VJaMz3NgMg-nGDmDuo_ctluQxAp9Ul","全局佈防",
              "[" + "8612345678" + ":" + "|3400 00 000]","8612345678","|3400 00 000]");
    } catch (Exception e) {
      logger.info("samsung push error=" + e.getMessage());
      e.printStackTrace();
    }

//    sendCommonMessage();
//    sendOverrideMessage();

  }*/

//  public static void send_message_vivo_to_regid(String regid,String str_title,String str_big_body,String str_machine_account,String str_event_info) {
  public static void send_message_fcm_to_regid(String regid,String str_title,String str_big_body,String str_machine_account,String str_event_info) {
    /*System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
    //HTTP代理
    System.setProperty("http.proxyHost","127.0.0.1");
    System.setProperty("http.proxyPort",Integer.toString(1081));
    //HTTPS代理
    System.setProperty("https.proxyHost","127.0.0.1");
    System.setProperty("https.proxyPort",Integer.toString(1081));*/


//    sendCommonMessage();
    /*try {
      sendOverrideMessage(regid,str_title,str_big_body,str_machine_account,str_event_info);
    } catch (IOException e) {
      logger.info("send_message_fcm_to_regid,error=",e);
      e.printStackTrace();
    }*/
  }

  public static void send_message_fcm_to_regid_language(String regid,String str_title,String str_big_body,String str_machine_account,String str_event_info,String str_language) {
    /*System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
    //HTTP代理
    System.setProperty("http.proxyHost","127.0.0.1");
    System.setProperty("http.proxyPort",Integer.toString(1081));
    //HTTPS代理
    System.setProperty("https.proxyHost","127.0.0.1");
    System.setProperty("https.proxyPort",Integer.toString(1081));*/


//    sendCommonMessage();
    try {
      sendOverrideMessage_language(regid,str_title,str_big_body,str_machine_account,str_event_info,str_language);
    } catch (IOException e) {
      logger.info("send_message_fcm_to_regid,error=",e);
      e.printStackTrace();
    }
  }

}
